#include <ESP8266WiFi.h>

#include <Arduino.h>
#include "PubSubClient.h"   ////A client library for MQTT messaging.
#include <ArduinoJson.h>

#include <stdio.h>  
#include <stdlib.h>

/* 连接WIFI SSID和密码 */
#define WIFI_SSID         "iQOO Neo5"		//待更改 热点名称
#define WIFI_PASSWD       "czf666666"		//待更改 热点密码

/* 设备的三元组信息*/				//需更改 云平台信息 以下为我阿里云所用信息
#define PRODUCT_KEY       "a1jBWZqwUM3"
#define DEVICE_NAME       "ESP8266"
#define DEVICE_SECRET     "da2f11ec4fcd8537a001667753fcbceb"
#define REGION_ID         "cn-shanghai"

/* 线上环境域名和端口号，不需要改 */
#define MQTT_SERVER       PRODUCT_KEY".iot-as-mqtt."REGION_ID ".aliyuncs.com"
#define MQTT_PORT         1883
#define MQTT_USRNAME      DEVICE_NAME"&"PRODUCT_KEY

#define CLIENT_ID         "a1jBWZqwUM3.ESP8266|securemode=2,signmethod=hmacsha256,timestamp=1728361842256|"
#define MQTT_PASSWD       "f7a6cccf19d2cae5254d150757a58d17cdd2da0e8b80eebb494b823428a77047"

//宏定义订阅主题
#define ALINK_BODY_FORMAT         "{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST     "/a1jBWZqwUM3/ESP8266/user/ESP8266"
 
const char* TOPIC = "/sys/a1jBWZqwUM3/ESP8266/thing/service/property/set"; 
unsigned long lastMs = 0;

WiFiClient espClient;
PubSubClient  client(espClient);

// 传感器数据
struct SensorData {
  float temperature = 0.0;
  float humidity = 0.0;
  char status = 'N';
} sensorData;

// 串口通信配置
const int BUFFER_SIZE = 10;  // "t=60h=25A" + 结束符 = 10字符
char serialBuffer[BUFFER_SIZE];
unsigned long lastReceivedTime = 0;
bool dataReady = false;

int psw[4] = {-1 ,-1 ,-1 ,-1};
int PSW_LENGTH = 4;


//连接wifi
void wifiInit()
{
    WiFi.begin(WIFI_SSID, WIFI_PASSWD);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        Serial.println("WiFi not Connect");
    }
}

//mqtt连接
void mqttConnect()
{
    while (!client.connected())
    {
        Serial.println("Connecting to MQTT Server ...");
        if(client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD))
        {
          Serial.println("MQTT Connected!");
        }
        else{
           Serial.print("MQTT Connect err:");
            Serial.println(client.state());
            delay(5000);
          }
        
    }
}

// 改进型数据解析
void parseSensorData() {
  // 格式验证：至少需要9个字符（t=xxh=xxX）
  if (strlen(serialBuffer) < 9) return;

  // 解析温度
  char* tPos = strstr(serialBuffer, "t=");
  if (tPos && (tPos - serialBuffer) <= 2) { // 确保t=在前部
    char tempStr[3] = {0};
    strncpy(tempStr, tPos+2, 2);
    sensorData.temperature = atoi(tempStr);
  }

  // 解析湿度
  char* hPos = strstr(serialBuffer, "h=");
  if (hPos && (hPos - tPos) == 4) { // 确保格式为t=xxh=xx
    char humiStr[3] = {0};
    strncpy(humiStr, hPos+2, 2);
    sensorData.humidity = atoi(humiStr);
  }

  // 解析状态（最后一个有效字符）
  sensorData.status = serialBuffer[strlen(serialBuffer)-1];
}

// 生成随机密码
void generateRandomPsw() {
  randomSeed(millis()); // 用时间初始化随机种子
  for (int i = 0; i < PSW_LENGTH; i++) {
      psw[i] = random(0, 10); // 生成0-9的随机数
  }
}
// 清空密码数组
void clearPswArray() {
  memset(psw, 0, sizeof(psw));
}

// 串口数据接收（带超时检测）
void receiveSerialData() {
  static byte index = 0;
  
  while (Serial.available() > 0) {
    char c = Serial.read();
    
    // 重置缓冲区如果收到起始符't'
    if (c == 't' && index == 0) {
      memset(serialBuffer, 0, BUFFER_SIZE);
      index = 0;
    }
    
    if (index < BUFFER_SIZE-1) {
      serialBuffer[index++] = c;
    }
    
    lastReceivedTime = millis();
  }

  // 超时处理（50ms无新数据视为帧结束）
  if (millis() - lastReceivedTime > 50 && index > 0) {
    serialBuffer[index] = '\0';
    dataReady = true;
    index = 0;
  }
}

// MQTT数据上报
void reportSensorData() {
  char payload[128];
  snprintf(payload, sizeof(payload),
    "{\"temp\":%.0f,\"humi\":%.0f,\"status\":\"%c\",\"id\":%d}",
    sensorData.temperature,
    sensorData.humidity,
    sensorData.status,
    1
  );
  
  if (client.publish(ALINK_TOPIC_PROP_POST, payload)) {
    // Serial.print("Data Sent: ");
    Serial.println(payload);
  } else {
    // Serial.println("Publish Failed");
  }
}
// 发送密码到云端
void sendPswViaMqtt() {
  char payload[128];
  snprintf(payload, sizeof(payload), 
      "{\"password\":[%d,%d,%d,%d]}",
      psw[0], psw[1], psw[2], psw[3]
  );
  
  if (client.publish(ALINK_TOPIC_PROP_POST, payload)) {
      // Serial.print("Password Sent: ");
      Serial.println(payload);
  } else {
      // Serial.println("Password Publish Failed");
  }
}

//回调函数
void callback(char* topic, byte* payload, unsigned int length) {
  // Serial.print("Message arrived [");
  // Serial.print(topic);   // 打印主题信息
  // Serial.print("] ");
  for (int i = 0; i < length; i++) {
    // Serial.print((char)payload[i]); // 打印主题内容
  }
  // Serial.println();

 DynamicJsonDocument doc(1024);  //创建了一个名为 doc 的动态 JSON 文档
 deserializeJson(doc, String((char *)payload));  //从一个名为 payload 的数据中解析 JSON 数据并将其填充到 doc 中

// int re = doc["params"]["led"];
// int a = doc["led"];

int door = doc["door"];
int lock = doc["password"];
int hot = doc["heater"];

// DynamicJsonDocument params = doc["params"];

  // Serial.println(a);
  // Serial.println(door);
  // Serial.println(lock);
  // Serial.println(hot);
// if(hot)
// {
  if(hot == 123)
  {
     Serial.println("@HOTON");
  }

  if(hot  == 234)
  {
     Serial.println("@HOTOFF");
  }
// }
// if(door)
// {
  if(door == 33)
  {
      Serial.println("@LOCKON");
  }
// }
if(lock)
{
  Serial.print("@");
  Serial.println(lock);
}

}


void setup() {
  Serial.begin(115200);
  Serial.println("\nSystem Initializing...");
  
  wifiInit();
  client.setServer(MQTT_SERVER, MQTT_PORT);
  client.setCallback(callback);
  
  // 初始化缓冲区
  memset(serialBuffer, 0, BUFFER_SIZE);
}

void loop() {
  static char prev_status = 'B'; // 跟踪上一次状态

  receiveSerialData();
  
  if (dataReady) {
    parseSensorData();
    dataReady = false;
    
    // 调试输出
    // Serial.print("Raw Data: ");
    Serial.println(serialBuffer);
    // Serial.printf("Parsed: T=%.0f, H=%.0f, S=%c\n",
    //              sensorData.temperature,
    //              sensorData.humidity,
    //              sensorData.status);
  }



  if (!client.connected()) {
    mqttConnect();
  }
  client.loop();



  static unsigned long lastReport = 0;
  if (millis() - lastReport >= 5000) {
    lastReport = millis();
    reportSensorData();

    // 检查状态变化
    if (sensorData.status == 'B' && prev_status == 'A') {    
      generateRandomPsw();
      // Serial.print("Password: ");
      // Serial.print(psw[0]);
      // Serial.print(psw[1]);
      // Serial.print(psw[2]);
      // Serial.println(psw[3]);
      
      sendPswViaMqtt();

      Serial.print("@");
      Serial.print(psw[0]);
      Serial.print(psw[1]);
      Serial.print(psw[2]);
      Serial.println(psw[3]);
    }
    prev_status = sensorData.status; // 更新状态
  }

}